package com.fzu.geometa.validate.util;

import com.occamlab.te.parsers.XMLValidatingParser;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;

public class XmlValidator {

    private static DocumentBuilder docBuilder;
    private static XMLValidatingParser iut;

    static {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        iut = new XMLValidatingParser();
        try {
            docBuilder = dbf.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
    }

    private Document schemaRefs;
    private  StringWriter strWriter;

    public XmlValidator( String schemaRefsPath, StringWriter strWriter) throws IOException, SAXException {
        this.schemaRefs = parseResourceDocument(schemaRefsPath);
        this.strWriter = strWriter;
    }

    public boolean validateByUrl(String testUrl) throws IOException {
        URL url = new URL(testUrl);
        return validateByUrl(url);
    }

    public boolean validateByUrl(URL testUrl) throws IOException {
        URLConnection uc = testUrl.openConnection();
        PrintWriter logger = new PrintWriter(strWriter);
        Document result = iut.parse(uc, schemaRefs.getDocumentElement(), logger);
        return result != null;
    }

    public boolean validateByXmlStr(String xmlStr) throws Exception {
        PrintWriter logger = new PrintWriter(strWriter);
        ByteArrayInputStream input = new ByteArrayInputStream(xmlStr.getBytes());
        Document result = iut.parseByInputStream(input, schemaRefs.getDocumentElement(), logger);
        return result != null;
    }

    private Document parseResourceDocument(final String resourcePath)
            throws SAXException, IOException {
        InputStream inputStream = getClass().getResourceAsStream(resourcePath);
        final Document doc = docBuilder.parse(inputStream);
        doc.setDocumentURI("classpath:" + resourcePath);
        return doc;
    }
}
